<template>
  <div class="container">
    <!-- 自定义滚动容器 -->
    <div 
      class="scroll-container" 
      ref="scrollContainer"
    >
      <div class="scroll-content">
        <p v-for="(item, i) in dataList" :key="i">容器滚动内容 {{ item }}</p>
        
        <!-- 加载更多状态提示 -->
        <div class="loading-status" v-if="isLoading">
          加载中...
        </div>
        <div class="loading-status" v-if="!hasMore && !isLoading">
          已加载全部内容
        </div>
      </div>
    </div>

    <!-- 回到顶部按钮 -->
    <button 
      class="container-back-to-top" 
      @click="scrollContainerToTop"
      v-if="containerShowBackTop"
    >
      容器顶部
    </button>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import { throttle } from 'lodash'; // 引入节流函数优化性能

// 滚动容器引用
const scrollContainer = ref(null);
// 容器滚动位置
const containerScrollTop = ref(0);
// 控制回到顶部按钮显示
const containerShowBackTop = ref(false);

// 列表数据
const dataList = ref(Array.from({ length: 50 }, (_, i) => i + 1)); // 初始50条数据
// 加载状态
const isLoading = ref(false); // 是否正在加载
const hasMore = ref(true); // 是否还有更多数据
let currentPage = 1; // 当前页码（非响应式，仅内部使用）

// 容器滚动事件处理函数（用节流限制频率，300ms一次）
const handleContainerScroll = throttle(() => {
  if (!scrollContainer.value) return;
  
  const container = scrollContainer.value;
  // 获取滚动相关参数
  const { scrollTop, clientHeight, scrollHeight } = container;
  
  // 1. 更新滚动位置和回到顶部按钮显示状态
  containerScrollTop.value = scrollTop;
  containerShowBackTop.value = scrollTop > 300;

  // 2. 判断是否滚动到底部（距离底部100px内）
  const distanceToBottom = scrollHeight - scrollTop - clientHeight;
  if (distanceToBottom < 100 ) {
      loadMoreData(); // 触发加载更多
  }
}, 300); // 节流：300ms内只执行一次

// 加载更多数据
const loadMoreData = async () => {
  isLoading.value = true; // 开始加载
  try {
    // 模拟接口请求延迟
    await new Promise(resolve => setTimeout(resolve, 1000));
    
    // 模拟请求到的新数据（每次加载20条，最多加载3页）
    currentPage++;
    const newData = Array.from({ length: 20 }, (_, i) => {
      return dataList.value.length + i + 1;
    });
    
    // 添加新数据到列表
    dataList.value = [...dataList.value, ...newData];
    
    // 模拟数据上限：最多加载3页（初始1页+2次加载）
    if (currentPage >= 3) {
      hasMore.value = false; // 没有更多数据
    }
  } catch (err) {
    console.error('加载失败:', err);
  } finally {
    isLoading.value = false; // 结束加载
  }
};

// 回到顶部
const scrollContainerToTop = () => {
  if (scrollContainer.value) {
    scrollContainer.value.scrollTo({
      top: 0,
      behavior: 'smooth'
    });
  }
};

// 挂载时添加滚动监听
onMounted(() => {
  nextTick(() => { // 确保DOM渲染完成
    if (scrollContainer.value) {
      scrollContainer.value.addEventListener('scroll', handleContainerScroll);
    }
  });
});

// 卸载时移除监听（避免内存泄漏）
onUnmounted(() => {
  if (scrollContainer.value) {
    scrollContainer.value.removeEventListener('scroll', handleContainerScroll);
  }
});
</script>

<style scoped>
.container {
  position: relative;
  width: 100%;
  height: 400px; /* 容器固定高度 */
}

.scroll-container {
  width: 100%;
  height: 100%;
  overflow-y: auto; /* 允许纵向滚动 */
}

.scroll-content {
  padding: 20px;
}

/* 加载状态样式 */
.loading-status {
  padding: 15px;
  text-align: center;
  color: #666;
  font-size: 14px;
}

/* 回到顶部按钮 */
.container-back-to-top {
  position: absolute;
  bottom: 20px;
  right: 20px;
  padding: 5px 10px;
  background: #6c757d;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

/* 列表项样式 */
.scroll-content p {
  padding: 10px 0;
  border-bottom: 1px solid #eee;
}
</style>